<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>函数的扩展</title>
	</head>
	<body>
		<script type="text/javascript">
			// 函数参数可设默认值
			// ES6 之前，不能直接为函数的参数指定默认值，只能采用变通的方法
			function log(s) {
				s = s || 'Hello World';
				console.log(s);
			}
			//ES6写法
			function log(s = 'Hello World') {
				console.log(s);
			}

			// 与解构赋值默认值结合使用
			// 加`={}`保证空参调用（foo();）不会报错
			function foo({
				x,
				y = 5
			} = {}) {
				console.log(x, y);
			}

			// 函数的 length 属性
			// 指定了默认值后，length属性将失真
			// 如果设置了默认值的参数不是尾参数，那么length属性也不再计入后面的参数了
			(function(a) {}).length; // 1
			(function(a = 5) {}).length; // 0
			(function(a, b, c = 5) {}).length; // 2
			(function(a, b = 1, c) {}).length; // 1
			(function(...args) {}).length ;// 0

			// 函数的name属性，返回该函数的函数名
			function foo() {}
			foo.name // "foo"
			// 如果将一个匿名函数赋值给一个变量，ES5 的name属性，会返回空字符串，而 ES6 的name属性会返回实际的函数名
			var f = function() {};
			// ES5
			f.name // ""
			// ES6
			f.name // "f"

			// ES6 允许使用“箭头”（=>）定义函数
			var fun = v => v;
			// 等同于
			var fun = function(v) {
				return v;
			};
			// 注意，箭头函数里面没有自己的this，而是引用外层的this
			function foo() {
				setTimeout(() => {
					console.log('id:', this.id);
				}, 100);
			}
			// 如果未使用箭头函数，本应该是21，但引用外层this的id本变为42
			var id = 21;
			foo.call({
				id: 42
			}); // id: 42

			// catch 命令的参数省略
			// 以前
			try {
				// ...
			} catch (err) {
				// ...
			}
			//现在，很多时候，catch代码块可能用不到这个参数，ES2019 做出了改变，允许catch语句省略参数
			try {
				// ...
			} catch {
				// ...
			}
		</script>
	</body>
</html>
